Manipulación de datos

Residencia de Epidemiología

Introducción


La manipulación de datos agrupa todas las tareas necesarias para la gestión de las variables:

  • su transformación,
  • la creación de nuevas variables,
  • los cambios de escala,
  • el formateo de categorías,
  • el filtro de algunas observaciones, etc.,
  • es decir, todo aquello que debamos hacer con los datos antes o durante el analisis.

Paquete dplyr

  • dplyr es el paquete para transformar datos que pertenece al ecosistema tidyverse

  • Implementa una gramática “humana”

  • Está constituido por funciones definidas como “verbos”

  • Las funciones primarias son: select(), filter(), arrange(), mutate() y summarise()

  • Otras funciones útiles son: rename(), group_by(), count(), if_else(), case_when(), beteewn(), across(), rowwise(), etc.

select()

La función select() del inglés seleccionar, sirve para seleccionar variables (columnas) de una tabla de datos.

select(datos, a, c)  

datos |> select(a, c)

Ayudantes de selección

Además existe un abanico de funciones que ayudan a una mejor selección de nombres de variables.

  • everything(): coincide con todas las variables.

  • group_cols(): seleccione todas las columnas de agrupación.

  • starts_with(): comienza con un prefijo.

  • ends_with(): termina con un sufijo.

  • contains(): contiene una cadena literal.

  • matches(): coincide con una expresión regular.

  • num_range(): coincide con un rango numérico como x01, x02, x03.

  • all_of(): coincide con nombres de variables en un vector de caracteres.

  • any_of(): igual que all_of(), excepto que no se genera ningún error para los nombres que no existen.

  • where(): aplica una función a todas las variables y selecciona aquellas para las cuales la función regresa TRUE.

Ejemplo de select()


  [1] "Anio"              "Escuela"           "F1_FNac"          
  [4] "F2_Edad"           "F3_Sexo"           "F4_Abuelos"       
  [7] "F4_Hermanos"       "F4_Madrastra"      "F4_Madre"         
 [10] "F4_Otros"          "F4_Padrastro"      "F4_Padre"         
 [13] "F5_Amigo"          "F5_Familiar"       "F5_Nadie"         
 [16] "F5_Novio"          "F5_Otro"           "F5_Profesional"   
 [19] "F6_amigos"         "F7_Acompaniado"    "F8_novio"         
 [22] "F9_CuantoTiempo"   "FKEY"              "GlobalRecordId"   
 [25] "H1_Alcohol"        "H1_Bblancas"       "H1_Cerveza"       
 [28] "H1_CuantosDias"    "H1_CuantosVasos"   "H1_Fernet"        
 [31] "H1_Otra"           "H1_Vino"           "H2_Cigarrillos"   
 [34] "H2_Cuantos"        "H3_Cuantos"        "H3_Marihuana"     
 [37] "H4_Cual"           "H4_OtraDroga"      "H5_HoraDormir"    
 [40] "H6_Almuerzo"       "H6_Cena"           "H6_Desayuno"      
 [43] "H6_Merienda"       "H6_Motivado"       "H6A_Calle"        
 [46] "H6A_Casa"          "H6A_ConQuien"      "H6A_Escuela"      
 [49] "H6C_Calle"         "H6C_Casa"          "H6C_ConQuien"     
 [52] "H6C_Escuela"       "H6D_Calle"         "H6D_Casa"         
 [55] "H6D_ConQuien"      "H6M_Calle"         "H6M_Casa"         
 [58] "H6M_ConQuien"      "H6M_Escuela"       "HD6_Escuela"      
 [61] "S1_ControlSalud"   "S2_Cual"           "S2_ECronica"      
 [64] "S3_Anticonceptivo" "S3_Cual"           "S3_Edad"          
 [67] "S3_EdadPareja"     "S3_Relaciones"     "S4_CoitoI"        
 [70] "S4_Cual"           "S4_DiaDespues"     "S4_DIU"           
 [73] "S4_Inyecciones"    "S4_Ninguno"        "S4_Otro"          
 [76] "S4_Pastillas"      "S4_Perodo"         "S4_Preservativos" 
 [79] "S5_Embarazo"       "S6_Hijos"          "SYSTEMDATE"       
 [82] "T1_Artemarcial"    "T1_Bailar"         "T1_Basket"        
 [85] "T1_Correr"         "T1_Deporte"        "T1_Futbol"        
 [88] "T1_Gimnasio"       "T1_Hockey"         "T1_Natacion"      
 [91] "T1_Rugby"          "T1_Skate"          "T1_Surf"          
 [94] "T1_Tenis"          "T1_Veces"          "T1_Voley"         
 [97] "T2_Amigos"         "T2_Calle"          "T2_Casas"         
[100] "T2_Centro"         "T2_Club"           "T2_Otros"         
[103] "T2_Plaza"          "T3_Bailar"         "T3_Matinee"       
[106] "T3_Noche"          "T4_Compu"          "T4_Leer"          
[109] "T4_Libros"         "T4_Revistas"       "T5_Conectas"      
[112] "T5_Redes"          "T6_Consiste"       "T6_Empleo"        
[115] "T6_Horas"          "T7_Cual"           "T7_Iglesia"       
[118] "T7_Religion"       "Turno"             "V1_Alegre"        
[121] "V1_Enojado"        "V1_Nervioso"       "V1_Preocupado"    
[124] "V1_Solo"           "V1_Tranquilo"      "V1_Triste"        
[127] "V2_SentisEscuela"  "V3_Casa"           "V3_Escuela"       
[130] "V3_Pareja"         "V3_Violencia"      "V4_Futuro"        
[133] "V5_Cuales"         "V5_Derechos"       "V5_Drogas"        
[136] "V5_Habitos"        "V5_Otros"          "V5_Ssexual"       
[139] "V5_Violencia"      "UniqueKey"        
# seleccionamos solo variables que comienzan con "F5" 
datos |> 
  select(starts_with("F5")) |> names()
[1] "F5_Amigo"       "F5_Familiar"    "F5_Nadie"       "F5_Novio"      
[5] "F5_Otro"        "F5_Profesional"

rename()

La función rename() posibilita renombrar a las variables de una tabla de datos.

La estructura básica es:

rename(datos, new_name = old_name)  

datos |> rename(new_name = old_name)

La variación rename_with() permite renombrar variables de una tabla a través de aplicar determinadas funciones.

La estructura básica de esta función es:

rename_with(datos, función, variables)  

datos |> rename_with(función, variables)

Ejemplo de rename() y rename_with()


# renombramos F2_Edad por EDAD

datos |> 
  rename(EDAD = F2_Edad) 
[1] "EDAD"
# renombramos el grupo de variables que comienza con F5 
# por sus nombres en minúsculas

datos |> 
  rename_with(.fn = tolower, .cols = starts_with("F5")) 
[1] "f5_amigo"       "f5_familiar"    "f5_nadie"       "f5_novio"      
[5] "f5_otro"        "f5_profesional"

filter()


La función filter() del inglés filtrar, sirve para filtrar un subconjunto de observaciones (filas) de una tabla de datos a partir de una condición.

Para construir la condición se utilizan una serie de operadores de comparación y operadores lógicos similares a la de otros lenguajes de programación.

La estructura de la función puede ser cualquiera de las siguientes:


filter(datos, condición)

datos |> filter(condición)

Operadores de comparación

Operadores lógicos (booleanos)

Operadores lógicos (booleanos)

Ejemplo de filter()


# filtramos observaciones que cumplan con la siguiente condición
datos |> 
  filter(F3_Sexo == 1, 
         between(F2_Edad, 17, 20), 
         H1_Cerveza == TRUE | H1_Vino == TRUE) |> 
  select(F3_Sexo, F2_Edad, H1_Cerveza, H1_Vino)
# A tibble: 23 × 4
   F3_Sexo F2_Edad H1_Cerveza H1_Vino
     <dbl>   <dbl> <lgl>      <lgl>  
 1       1      18 TRUE       FALSE  
 2       1      17 TRUE       TRUE   
 3       1      18 TRUE       FALSE  
 4       1      17 TRUE       TRUE   
 5       1      17 FALSE      TRUE   
 6       1      19 TRUE       TRUE   
 7       1      18 TRUE       TRUE   
 8       1      17 TRUE       TRUE   
 9       1      18 TRUE       TRUE   
10       1      18 TRUE       TRUE   
# ℹ 13 more rows

arrange()


La función arrange() del inglés ordenar, sirve para ordenar observaciones de una tabla de datos a partir de una o más variables (columnas).


arrange(datos, var1, var2, ...)   

datos |> arrange(var1, var2, ...) 

arrange()


El ordenamiento predeterminado es ascendente.

Si la variable contiene números, las filas se van a ordenar ubicando esos números de menor a mayor (1,2,3…). Si es texto, las filas se van a ordenar ubicando las palabras alfabéticamente en forma ascendente (a,b,c…).

Si deseamos invertir el orden debemos incorporar la función desc() dentro de arrange().


datos |> arrange(var1)  # ascendente

datos |> arrange(desc(var1)) # descendente

mutate()


La función mutate() del inglés mutar o transformar, sirve para crear nuevas variables, a partir de los valores de otras variables, dentro de la tabla de datos.

La o las nuevas variables creadas se incorporan al final de las columnas del conjunto de datos.

Dentro de los argumentos de mutate() se aplican funciones vectorizadas, lo que significa que la función toma un vector de valores como entrada y devuelve el mismo número de valores como salida.


datos |> mutate(nueva_var = operación/función)

mutate()

Algunas de las operaciones y funciones vectorizadas provistas por el lenguaje R son:

  • Operadores aritméticos - +, -, *, /, ^

  • Aritmética modular - %/% - %%

  • Transformación - escala - log() - log2() - log10() - exp() - sqrt()

  • Comparaciones - >, >=, <, <=, ==, !=

  • Atrasos/adelantos - lag() - lead()

  • Ordenamiento - min_rank() - percent_rank(), etc…

  • Acumulativos - cumsum() - cummean() - etc…

  • Condicional - if_else() - case_when().

Ejemplo de mutate()


Coercionamos la variable aplicando dmy() y as_date()

datos |> select(F1_FNac)
# A tibble: 1,252 × 1
   F1_FNac           
   <chr>             
 1 29/3/1999 00:00:00
 2 27/2/2003 00:00:00
 3 15/3/2000 00:00:00
 4 13/8/2001 00:00:00
 5 13/8/1998 00:00:00
 6 29/3/2001 00:00:00
 7 <NA>              
 8 20/4/1997 00:00:00
 9 17/1/2001 00:00:00
10 27/8/2002 00:00:00
# ℹ 1,242 more rows
datos |> 
  mutate(F1_FNac = dmy_hms(F1_FNac),
         F1_FNac = as_date(F1_FNac)) |> 
  select(F1_FNac)
# A tibble: 1,252 × 1
   F1_FNac   
   <date>    
 1 1999-03-29
 2 2003-02-27
 3 2000-03-15
 4 2001-08-13
 5 1998-08-13
 6 2001-03-29
 7 NA        
 8 1997-04-20
 9 2001-01-17
10 2002-08-27
# ℹ 1,242 more rows

summarise()


La función summarise() del inglés resumir, se utiliza justamente para resumir las observaciones de una tabla de datos mediante alguna medida resumen.

Otra forma de escribir la función es summarize(). Ambas realizan la misma operación.


datos |> summarise(var_resumen = función_resumen)

datos |> summarize(var_resumen = función_resumen)

summarise()


Algunas de las funciones resumen provistas por el lenguaje R son:

  • tendencia central - mean() - median()

  • posición - min() - max() - quantile()

  • dispersión - var() - sd() - IQR()

  • conteo - n() - n_distinct()

  • orden - first() - last()

La mayoría de estas funciones aplican en tipos de datos int (enteros), dbl (reales), date (fecha) y ddtm (fecha - hora).

Ejemplo de summarise()



# Resumimos la variable F2_Edad calculando media, 
# desvío estandar, mínimo y máximo

datos |> 
  summarise(Media = mean(F2_Edad, na.rm = T),
            Desvio = sd(F2_Edad, na.rm = T),
            Min = min(F2_Edad, na.rm = T),
            Max = max(F2_Edad, na.rm = T)) 
# A tibble: 1 × 4
  Media Desvio   Min   Max
  <dbl>  <dbl> <dbl> <dbl>
1  14.5   1.46    10    19

group_by()


La función group_by() del inglés agrupar por, sirve para agrupar a partir de valores o categorías distintas.

Aplicado sólo no produce ningún resultado interesante, por eso está pensando para usarlo principalmente asociado a summarise().


datos |> group_by(variable)


Junto a esta función aparece ungroup() que deshace el agrupamiento.


datos |> ungroup()

Ejemplo de group_by()

# Resumimos la variable F2_Edad según Anio 
# calculando media, desvío estandar, mínimo y máximo

datos |> 
  group_by(Anio) |> 
  summarise(Media = mean(F2_Edad, na.rm = T),
            Desvio = sd(F2_Edad, na.rm = T),
            Min = min(F2_Edad, na.rm = T),
            Max = max(F2_Edad, na.rm = T)) 
# A tibble: 2 × 5
  Anio  Media Desvio   Min   Max
  <chr> <dbl>  <dbl> <dbl> <dbl>
1 2do.   13.7   1.03    10    18
2 4to.   15.8   1.06    13    19

Agrupamiento en summarise()


El agrupamiento o estratificación producido por group_by() es permanente mientras no desagrupemos y esto a veces ocasiona problemas.


En la última versión de dplyr se agregó un argumento en summarise() para lograr agrupamientos temporales, donde no hace falta desagrupar posteriomente al resultado.


datos |> summarise(.by = variable_grupo)

Ejemplo con .by en summarise()

# Resumimos la variable F2_Edad según Anio con .by
# calculando media, desvío estandar, mínimo y máximo

datos |> 
  summarise(Media = mean(F2_Edad, na.rm = T),
            Desvio = sd(F2_Edad, na.rm = T),
            Min = min(F2_Edad, na.rm = T),
            Max = max(F2_Edad, na.rm = T),
            .by = Anio) 
# A tibble: 2 × 5
  Anio  Media Desvio   Min   Max
  <chr> <dbl>  <dbl> <dbl> <dbl>
1 4to.   15.8   1.06    13    19
2 2do.   13.7   1.03    10    18

count()


La función count() del inglés contar, sirve para contabilizar categorías o valores diferentes de variables resumiendo los datos en una tabla de frecuencia.

Reconoce y también contabiliza los valores NA de las variables.

datos |> count(variable)

Tiene algunos argumentos opcionales como:

  • name (nombre de la variable que contabiliza - por defecto se llama n)
  • sort (si es TRUE se ordena de mayor a menor)
  • wt (variable peso / ponderación / expansión opcional)

También se pueden agregar más variables separadas por una coma.

Ejemplo de count()


# Contamos las frecuencias de la variable Anio
# ordenadas de mayor a menor

datos |> 
  count(Anio, sort = T)
# A tibble: 2 × 2
  Anio      n
  <chr> <int>
1 2do.    750
2 4to.    502

if_else()


La función if_else() devuelve valores dependiendo del resultado de una condición lógica (TRUE/FALSE).

Los valores devueltos para cada observación se almacenan dentro de una variable definida en mutate().


datos |> 
  mutate(x = if_else(condicion, valor_T, valor_F))

Ejemplo de if_else()

datos |> 
  summarise(Mediana_edad = median(F2_Edad, na.rm = T))
# A tibble: 1 × 1
  Mediana_edad
         <dbl>
1           14
# dividimos en dos grupos según la mediana de edad
datos |> 
  mutate(Grupo_edad = if_else(F2_Edad <= 14, "<= 14", "> 14")) |>
  count(Grupo_edad) 
# A tibble: 3 × 2
  Grupo_edad     n
  <chr>      <int>
1 <= 14        597
2 > 14         583
3 <NA>          72

case_when()


La función case_when() ejecuta una vectorización múltiple de funciones if_else().

Los valores devueltos para cada observación se almacenan dentro de una variable definida en mutate().


datos |> 
  mutate(x = case_when(
    condicion ~ valor_T, 
    ...,
    .default = valor))

Ejemplo de case_when()

# etiquetamos la variable V1_Alegre
datos |> 
  mutate(V1_Alegre = case_when(
    V1_Alegre == 0 ~ "Nada",
    V1_Alegre == 1 ~ "Poco",
    V1_Alegre == 2 ~ "Neutral",
    V1_Alegre == 3 ~ "Muy",
    V1_Alegre == 4 ~ "Totalmente",
    .default = "Ns/Nc"
  )) |> 
  count(V1_Alegre, sort = T)
# A tibble: 6 × 2
  V1_Alegre      n
  <chr>      <int>
1 Totalmente   452
2 Muy          256
3 Neutral      249
4 Ns/Nc        171
5 Poco          80
6 Nada          44

between()


La función between() es una función atajo para operaciones de condición >= x <= , implementado para vectores numéricos o de fecha/hora.

Se utiliza dentro de estructuras donde se escriben condiciones (filter(), mutate(), etc).


datos |> filter(between(x, izquierda, derecha)) 


Los dos extremos (izquierda y derecha) se incluyen en el intervalo

Ejemplo de between()


# filtramos observaciones donde la variable F2_Edad sea mayor 
# o igual a 16 y menor o igual 18 años

datos |> 
 filter(between(F2_Edad, 16, 18)) |> 
  count(F2_Edad)
# A tibble: 3 × 2
  F2_Edad     n
    <dbl> <int>
1      16   153
2      17    95
3      18    29

Documentación


Capítulo 3 del libro “R for Data Science (2e)”